package com.youshang520i.ratelimiter.config.cglib;

import com.google.common.util.concurrent.RateLimiter;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.cglib.proxy.Enhancer;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

/**
 * @author youshang
 */
public class CglibFactory<T> implements FactoryBean<T> {

    private Class<T> interfaceClass;

    public CglibFactory(Class interfaceClass) {
        this.interfaceClass = interfaceClass;
    }

    @Override
    public T getObject() throws Exception {
        return (T) Enhancer.create(interfaceClass, new CglibProxy(this.initRateLimiter()));
    }

    @Override
    public Class<?> getObjectType() {
        return interfaceClass;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    /**
     * 初始化自定义注解获取参数
     *
     * @return
     */
    private RateLimiter initRateLimiter() {
        Method[] methods = this.interfaceClass.getMethods();
        for (Method method : methods) {
            com.youshang520i.ratelimiter.config.annotation.RateLimiter annotation = method.getAnnotation(com.youshang520i.ratelimiter.config.annotation.RateLimiter.class);
            if (null != annotation) {
                return this.createRateLimiter(annotation);
            }
        }
        return null;
    }

    /**
     * 创建令牌
     *
     * @param annotation
     * @return
     */
    private RateLimiter createRateLimiter(com.youshang520i.ratelimiter.config.annotation.RateLimiter annotation) {
        /**
         * 每秒发出5个令牌
         */
//    RateLimiter rateLimiter = RateLimiter.create(5.0D);
        /**
         * 每秒发出5个令牌 ,当前用于测试的RateLimiter每秒生成5个许可，即每生成1个许可需要约200毫秒，在创建时将预热期设置为10000毫秒，大于许可生成时间间隔。
         */
        RateLimiter rateLimiter = RateLimiter.create(annotation.permitsPerSecond(), annotation.warmupPeriod(), TimeUnit.MILLISECONDS);
        return rateLimiter;
    }
}
